/***************** ESPECIFICACIO LEX ***************/

/*

Exercici 1: Especificació FLEX del compilador C

Lluis Hernandez
Tomas Gonzalez

*/

/***************************************************/

%{
#include <stdio.h>
#include <math.h>
#include "Llista_id.h"
#include "parser.h"

int linea=1;
int id_identificador=0;

void salva_str(){
	yylval.ident.lexema=(char *)malloc(sizeof(char)*yyleng);
	strncpy(yylval.ident.lexema,yytext+1,yyleng-2);
}

void salva(){
    /*if(yyleng != strlen(yytext)){
        printf("Longitud DESPRES =>> %d\n",yyleng);
        yyleng=strlen(yytext);
        printf("Longitud TEORICA=>> %d\n",strlen(yytext));
        printf("Longitud ABANS =>> %d\n",yyleng);
    }*/
	yylval.ident.lexema=(char *)calloc(yyleng+1,sizeof(char));
	strncpy(yylval.ident.lexema,yytext,yyleng);
}

void next_line(){
	linea++;
	yylval.ident.line= linea;
	yylineno = linea;
}

%}


DIGIT 		[0-9]
ID		[a-zA-Z][a-zA-Z0-9_]*
EXP		[eE][-+]?{DIGIT}?
HEX		[a-fA-F0-9]
FL		(f|F|l|F)
STR		(["].+["])
CAR		(['][0-9a-zA-Z_/()?!$%&]['])
KEYS		(auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|range|register|return|short|signed|sizeof|static|struct|switch|type_name|typedef|union|unsigned|void|volatile|while)
others		([ ]|[\t]|[\v]|[\f])

%x	comments comment_s includes

%%

"..."		{
		salva();
		return ELLIPSIS;}

"\n"		{next_line();}

"/*"		BEGIN(comments);

"//"		BEGIN(comment_s);

"#"		BEGIN(includes);

 /* Afegides les operacions logiques*/
"&&"		return AND_OP;

"||"		return OR_OP;

 /*********************************/

"++"		return INC_OP;

"--"		return DEC_OP;

"=="		return EQ_OP;

"!="		return NE_OP;

"<="		return LE_OP;

">="		return GE_OP;

"*="		return MUL_ASSIG;

"/="		return DIV_ASSIG;

"%="		return MOD_ASSIG;

"+="		return ADD_ASSIG;

"-="		return SUB_ASSIG;

"<<="		return LEFT_ASSIG;

">>="		return RIGHT_ASSIG;

"&="		return AND_ASSIG;

"^="		return XOR_ASSIG;

"="		return '=';

"+"		return '+';

"-"		return '-';

"."		return '.';

":"		return ':';

"!"		return '!';

","		return ',';

"/"		return '/';

"*"		return '*';

"&"		return '&';

"|"		return '|';

"%"		return '%';

"^"		return '^';

"("		return '(';

")"		return ')';

"["		return '[';

"]"		return ']';

"{"		return '{';

"}"		return '}';

";"		return ';';
		
">"		return '>';

"<"		return '<';

{others}				

{DIGIT}+			 	{
					salva();
					return INTEGER_CONSTANT;
	  	     			}

(({DIGIT}+{EXP}{DIGIT}+("."{DIGIT})?)|({DIGIT}+"."{DIGIT}+{EXP}{DIGIT}+("."{DIGIT}+)?)|("."{DIGIT}+{EXP}{DIGIT}+)) {
					salva();
					return FLOATING_CONSTANT;
					}

(({DIGIT}+"."{DIGIT}+)|("."{DIGIT}+))	{
					salva();
					return FLOATING_CONSTANT;
					}

{ID}					{
					int res;
					res=Ll_Consultar(yytext);
					if(res != -1){
							salva();
							return res;
						}
					else 	{
						salva();
                        return IDENTIFIER;
						}
					}

{CAR}					{
					salva_str();
					return CHARACTER_CONSTANT;
					}

{STR}					{
					salva_str();
					return STRING;
					}


<includes>"\n"		{
			next_line();
			BEGIN(INITIAL);
			}

<includes>.

<comments>"*/"		{
			BEGIN(INITIAL);
			}

<comments>"\n"		{
			next_line();
			}
<comments>.		

<comment_s>"\n"		{
			next_line();
			BEGIN(INITIAL);
			}
<comment_s>.		


%%

int init_analisi_lexic(char *file_name)
{

int error;

yyin=fopen(file_name,"r");

if(yyin == NULL){
	error = EXIT_FAILURE;
}else{
	error = EXIT_SUCCESS;
}

return error;

}

int end_analisi_lexic(){

int error;

error = fclose(yyin);

if (error == 0){

error = EXIT_SUCCESS;
}else{
error = EXIT_FAILURE;
}
return error;

}


